package com.atguigu.gmall.realtime.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.flink.api.java.tuple.Tuple2;
import redis.clients.jedis.Jedis;

import java.util.List;

/**
 * Author: Felix
 * Date: 2021/9/18
 * Desc: 维度查询的工具类
 */
public class DimUtil {



    /**
     * 优化：旁路缓存
     * 思路：先从Redis中获取维度数据，如果获取到了，直接将结果返回进行关联；
     *      如果从Redis中没有获取到维度数据，那么再发送请求到Phoenix中去查询维度数据
     *      并将查询的结果放到Redis中
     * 分析：
     *      type:   String
     *      key:    dim:维度表表名:主键1_主键2
     *      expire: 1day
     */
    public static JSONObject getDimInfo(String tableName, String id){
        return getDimInfo(tableName,Tuple2.of("id",id));
    }

    public static JSONObject getDimInfo(String tableName, Tuple2<String,String>... colNameAndValues){
        //拼接维度查询条件
        StringBuilder selectSql = new StringBuilder("select * from "+tableName+" where ");
        //拼接查询Redis中维度的key
        StringBuilder redisKey = new StringBuilder("dim:"+tableName.toLowerCase()+":");

        for (int i = 0; i < colNameAndValues.length; i++) {
            Tuple2<String, String> colNameAndValue = colNameAndValues[i];
            String colName = colNameAndValue.f0;
            String colValue = colNameAndValue.f1;
            selectSql.append(colName + "='" + colValue +"' ");
            redisKey.append(colValue);
            if(i < colNameAndValues.length - 1){
                selectSql.append(" and ");
                redisKey.append("_");
            }
        }

        //先从Redis中查询数据
        Jedis jedis = null;
        String dimJsonStr = null;
        JSONObject dimJsonObj = null;

        try {
            jedis = RedisUtil.getJedis();
            dimJsonStr = jedis.get(redisKey.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("从Redis中查询维度数据失败");
        }

        //判断是否命中缓存
        if(dimJsonStr != null && dimJsonStr.length() >0){
            //如果命中  ，直接转换为对象返回
            dimJsonObj = JSON.parseObject(dimJsonStr);
        }else{
            //如果没有命中，再到Phoenix去查询
            System.out.println("查询维度表的sql:" + selectSql);
            //底层还是调用PhoenixUtil，从Phoenix表中查询维度的数据
            List<JSONObject> dimList = PhoenixUtil.queryList(selectSql.toString(), JSONObject.class);

            if(dimList != null && dimList.size() > 0){
                dimJsonObj = dimList.get(0);
                //将查询出来的数据 放到Redis中进行缓存
                if(jedis !=null){
                    jedis.setex(redisKey.toString(),24*60*60,dimJsonObj.toJSONString());
                }
            }else{
                System.out.println("~~维度数据没找到~~");
            }
        }

        //释放资源
        if(jedis !=null){
            System.out.println("--关闭Redis连接--");
            jedis.close();
        }

        return dimJsonObj;
    }

    public static JSONObject getDimInfoNoCache(String tableName, Tuple2<String,String>... colNameAndValues){
        //拼接维度查询条件
        StringBuilder selectSql = new StringBuilder("select * from "+tableName+" where ");
        for (int i = 0; i < colNameAndValues.length; i++) {
            Tuple2<String, String> colNameAndValue = colNameAndValues[i];
            String colName = colNameAndValue.f0;
            String colValue = colNameAndValue.f1;
            selectSql.append(colName + "='" + colValue +"' ");
            if(i < colNameAndValues.length - 1){
                selectSql.append(" and ");
            }
        }
        System.out.println("查询维度表的sql:" + selectSql);

        //底层还是调用PhoenixUtil，从Phoenix表中查询维度的数据
        List<JSONObject> dimList = PhoenixUtil.queryList(selectSql.toString(), JSONObject.class);
        JSONObject dimJsonObj = null;
        if(dimList != null && dimList.size() > 0){
            dimJsonObj = dimList.get(0);
        }else{
            System.out.println("~~维度数据没找到~~");
        }
        return dimJsonObj;
    }

    public static void main(String[] args) {
        //JSONObject dimJsonObj = getDimInfoNoCache("dim_base_trademark", Tuple2.of("id", "15"));
        //JSONObject dimJsonObj = getDimInfo("dim_base_trademark", Tuple2.of("id", "15"));
        JSONObject dimJsonObj = getDimInfo("dim_base_trademark", "15");
        System.out.println(dimJsonObj);
    }

    //根据key让Redis中的缓存失效
    public static  void deleteCached( String tableName, String id){
        String key = "dim:" + tableName.toLowerCase() + ":" + id;
        try {
            Jedis jedis = RedisUtil.getJedis();
            // 通过key清除缓存
            jedis.del(key);
            jedis.close();
        } catch (Exception e) {
            System.out.println("缓存异常！");
            e.printStackTrace();
        }
    }

}
